﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Revis.VClinicNet.App.Internal;
using Revis.VClinicNet.App.Internal.Dto;
using Revis.VClinicNet.UI.Internal.Mvc.Models.Forms;
using Revis.VClinicNet.App.Internal.Dto.Validation;
using Revis.VClinicNet.UI.Internal.Mvc.Extensions;
using Revis.VClinicNet.UI.Internal.Mvc.Infrastructure;
using Revis.VClinicNet.Core.Domain.Credentials;

namespace Revis.VClinicNet.UI.Internal.Mvc.Controllers
{
    public class EntryController : Infrastructure.ControllerBase
    {
        private IEntryService _entryService = null;
        private IVisitService _visitService = null;

        public EntryController(IEntryService ies, IVisitService ivs) :
            base("Entry")
        {
            _entryService = ies;
            _visitService = ivs;
        }

        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor | WorkerUserRole.Recepcionist)]
        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// Create  form model for visit id
        /// </summary>
        /// <param name="visitId">visit id</param>
        /// <param name="entry">model with already initialized values</param>
        /// <returns></returns>
        [NonAction]
        private ActionResult Create(long visitId, EntryCreateDto entry)
        {
            VisitInfoDto visit = _visitService.Find<VisitInfoDto>(visitId);
            if (visit == null) {
                return ErrorView("Nie znaleziono odpowiedniej wizyty", "Create");
            }
            entry = entry ?? new EntryCreateDto() {
                DoctorId = UserId,
                VisitId = visit.Id
            };
            return View(new EntryCreateFormModel(visit, entry));
        }

        /// <summary>
        /// Create empty entry form
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor)]
        public ActionResult Create(long id)
        {
            return Create(id, null);
        }

        /// <summary>
        /// Send filled up entry model to core and display errors if necessary
        /// </summary>
        /// <param name="entry"></param>
        /// <returns></returns>
        [HttpPost]
        [HistoryBackLinked(Type = BackLinkType.ModifyForm)]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor)]
        public ActionResult Create(EntryCreateDto entry)
        {
            try {
                long id = _entryService.Create(entry);
                return RedirectToAction("Detail", new { id = id });
            } catch (ValidationException ve) {
                ModelState.AddModelErrors(ve);
            } catch (ClinicException ce) {
                ModelState.AddErrorMessage(ce.Message);
            }
            return Create(entry.VisitId, entry);
        }

        /// <summary>
        /// Action to show entry detail
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor)]
        public ActionResult Detail(long id)
        {
            EntryDto entry = _entryService.Find<EntryDto>(id);
            if (entry == null) {
                return ErrorView("Nie znaleziono wpisu", "Detail");
            }
            return View(entry);
        }

        /// <summary>
        /// Action to show patient card
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [HistoryBackLinked]
        [AuthorizeFor(Role = WorkerUserRole.Administrator | WorkerUserRole.Doctor)]
        public ActionResult PatientCard(long id)
        {
            IList<EntryInfoDto> entries = null;
            entries = _entryService.PatientCard(id);
            return View(entries);
        }

    }
}
